package ee.ut.math.tvt.salessystem.domain.controller.impl;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;

import ee.ut.math.tvt.salessystem.domain.controller.SalesDomainController;
import ee.ut.math.tvt.salessystem.domain.data.Sale;
import ee.ut.math.tvt.salessystem.domain.data.SoldItem;
import ee.ut.math.tvt.salessystem.domain.data.StockItem;
import ee.ut.math.tvt.salessystem.domain.exception.VerificationFailedException;
import ee.ut.math.tvt.salessystem.util.HibernateUtil;

/**
 * Implementation of the sales domain controller.
 */
public class SalesDomainControllerImpl implements SalesDomainController {

	private static final Logger log = Logger.getLogger(SalesDomainControllerImpl.class);
	private Session session = HibernateUtil.currentSession();

	public void submitCurrentPurchase(List<SoldItem> goods) throws VerificationFailedException {

		// Begin transaction
		Transaction tx = session.beginTransaction();

		// construct new sale object
		Sale sale = new Sale(goods);
		sale.setId(null);

		sale.setSellingTime(new Date());
		session.save(sale);

		// Reduce quantities of stockItems in warehouse
		for (SoldItem item : goods) {
			StockItem stockItem = getStockItem(item.getStockItem().getId());
			item.setSale(sale);
			stockItem.setQuantity(stockItem.getQuantity() - item.getQuantity());
			session.save(stockItem);
		}

		// end transaction
		tx.commit();

	}

	private StockItem getStockItem(long id) {
		return (StockItem) session.get(StockItem.class, id);
	}

	public void cancelCurrentPurchase() throws VerificationFailedException {
		// XXX - Cancel current purchase
	}

	public void startNewPurchase() throws VerificationFailedException {
		// XXX - Start new purchase
	}

	public List<StockItem> loadWarehouseState() {
		return this.getAllStockItems();
	}

	@Override
	public List<Sale> getAllSales() {
		List<Sale> result = session.createQuery("from Sale").list();
		log.info(result.size() + " Sales loaded from disk");

		return result;
	}

	public List<StockItem> getAllStockItems() {
		List<StockItem> result = session.createQuery("from StockItem").list();

		log.info(result.size() + " items loaded from disk");
		return result;
	}

	public void endSession() {
		HibernateUtil.closeSession();
	}

	@Override
	public void saveStockItem(StockItem stockItem) {
		if (stockItem.getId() == 0) {
			stockItem.setId(null);
		}
		session.save(stockItem);
	}
}
